from ctypes import *
import time
import threading

class logitem(Structure):
    _fields_ = [("s", c_size_t)
              , ("buf", c_char*(256-8))
    ]

class CTX:
    def __init__(self,fn):
        self.fn  = fn
        self.lib = CDLL(fn)
        self.lib.context.restype = c_void_p
        self.lib.getLog.restype  = c_void_p
        self.loglevel = ['sys','debug','info','warn','error','fatal']
        self.callback = {}
        self.logon = False
    
    def open(self,tmp):    
        self.h = self.lib.context(tmp.encode(encoding="utf-8"))
    
    def startlog(self):
        if not self.logon:
            self.t = threading.Thread(target=self.logt)
            self.logon = True
            self.t.start()

    def log(self):
        for level in self.callback.keys():
            try:
                l = self.loglevel.index(level)
                ti = self.lib.log_len(c_void_p(self.h),c_int(l))
                for i in range(ti):
                    addr = self.lib.getLog(c_void_p(self.h),c_int(l))
                    vbuf = cast( addr, POINTER(logitem) )
                    item = vbuf.contents
                    if item.s>(256-8):
                        continue
                    else:
                        # item.buf[item.s] = 0
                        msg = item.buf.decode()
                        self.callback[level](msg)
            except Exception as e:
                print(e)    
    
    def logt(self):
        while self.logon:
            self.log()
            time.sleep(1)

    def stoplog(self):
        self.logon = False

    def getLog(self,levels=range(6)):
        r = {}
        for l in levels:
            ti = self.lib.log_len(c_void_p(self.h),c_int(l))
            r[self.loglevel[l]] = []
            for i in range(ti):
                addr = self.lib.getLog(c_void_p(self.h),c_int(l))
                vbuf = cast( addr, POINTER(logitem) )
                item = vbuf.contents
                if item.s>(256-8):
                    continue
                else:
                    msg = item.buf.decode('utf8')
                    r[self.loglevel[l]].append(msg)
        return r
                    